home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UUPC11QS.ARJ / UUSTAT.C < prev    next >
C/C++ Source or Header  |  1991-10-19  |  36KB  |  1,023 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    u u s t a t . c                                                 */
  3. /*                                                                    */
  4. /*    Job status report for UUPC/extended                             */
  5. /*                                                                    */
  6. /*                                                                    */
  7. /*    Copyright 1988 (C), Dewey Coffman                               */
  8. /*    Changes Copyright 1991 (C), Andrew H. Derbyshire                */
  9. /*--------------------------------------------------------------------*/
  10.  
  11. /*--------------------------------------------------------------------*/
  12. /*         System include files                                       */
  13. /*--------------------------------------------------------------------*/
  14.  
  15. #include <stdio.h>
  16. #include <io.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <string.h>
  20. #include <time.h>
  21. #include <fcntl.h>
  22. #include <stdlib.h>
  23.  
  24. /*--------------------------------------------------------------------*/
  25. /*         Local include files                                        */
  26. /*--------------------------------------------------------------------*/
  27.  
  28. #include "lib.h"
  29. #include "dater.h"
  30. #include "export.h"
  31. #include "getopt.h"
  32. #include "getseq.h"
  33. #include "hlib.h"
  34. #include "hostable.h"
  35. #include "hostatus.h"
  36. #include "import.h"
  37. #include "pushpop.h"
  38. #include "readnext.h"
  39. #include "security.h"
  40. #include "stater.h"
  41. #include "timestmp.h"
  42.  
  43. #define DAY (60l * 60l * 24l)
  44. #define ALL    "all"
  45. #define MAXL      128      /* MAX LINE LENGTH */
  46.  
  47. #define STRCREAT(s, s2, s3)\
  48.    strcpy(s, s2);\
  49.    strcat(s, s3);\
  50.  
  51. /*--------------------------------------------------------------------*/
  52. /*                          Local data types                          */
  53. /*--------------------------------------------------------------------*/
  54.  
  55. typedef enum {
  56.       POLL_CALL = 'P',
  57.       RECEIVE_CALL = 'R',
  58.       SEND_CALL = 'S'
  59.       } CALLTYPE;
  60.  
  61.  
  62. struct data_queue {
  63.    char name[FILENAME_MAX];
  64.    struct data_queue *next_link;
  65.    time_t created;
  66.    long size;
  67.    boolean execute;
  68.    char type;
  69. } ;
  70.  
  71. /*--------------------------------------------------------------------*/
  72. /*                             Verb list                              */
  73. /*--------------------------------------------------------------------*/
  74.  
  75. typedef enum {
  76.    LIST_DEFAULT = 1,
  77.    LIST_ALL,
  78.    LIST_ACCESS,
  79.    LIST_QUEUE,
  80.    KILL_JOB,
  81.    REFRESH_JOB,
  82.    FORCE_POLL
  83.    } COMMAND_CLASS;
  84.  
  85. /*--------------------------------------------------------------------*/
  86. /*                Processing to be taken by open_call                 */
  87. /*--------------------------------------------------------------------*/
  88.  
  89. typedef enum {
  90.    JOB_STATUS = 1,
  91.    JOB_KILL,
  92.    JOB_REFRESH
  93.    } CALL_ACTION;
  94.  
  95. /*--------------------------------------------------------------------*/
  96. /*                          Global variables                          */
  97. /*--------------------------------------------------------------------*/
  98.  
  99. currentfile();
  100.  
  101. static const char *host_status[] = {
  102.       "(invalid - entry not properly initialized)",
  103.       "(local host system)",
  104.       "(host for routing purposes only)",
  105.       "(host for gateway purposes only)",
  106.       "(alias of another host)",
  107.       "NEVER CALLED",
  108.       "TALKING",
  109.       "CALLBACK REQUIRED",
  110.       "DIAL FAILED",
  111.       "SCRIPT FAILED",
  112.       "MAX RETRY REACHED",
  113.       "RETRY TIME NOT REACHED",
  114.       "CALL SUCCEEDED",
  115.       "WRONG MACHINE NAME",
  116.       "UNKNOWN HOST",
  117.       "WRONG TIME TO CALL"
  118.    } ;
  119.  
  120. /*--------------------------------------------------------------------*/
  121. /*                        Internal prototypes                         */
  122. /*--------------------------------------------------------------------*/
  123.  
  124. static void all( const char *system, const char *userid );
  125.  
  126. static char *is_job(const char *jobid );
  127.  
  128. static void kill_job(const char *s);
  129.  
  130. static void long_stats( const char *system );
  131.  
  132. static void short_stats( const char *system );
  133.  
  134. static CALLTYPE open_call( const char *callname,
  135.                            const char *remote,
  136.                                  struct data_queue **current,
  137.                                  char *user,
  138.                                  char *sys,
  139.                            const CALL_ACTION action);
  140.  
  141. static void open_data(const char *file,
  142.                             char *user,
  143.                             char *sys,
  144.                             char *command);
  145.  
  146. static void poll(const char *callee);
  147.  
  148. static void print_all(       char *job,
  149.                        struct data_queue *current,
  150.                        const char *user,
  151.                        const char *sys);
  152.  
  153. static void refresh_job(const char *s);
  154.  
  155. static void touch( const char *fname );
  156.  
  157. static void usage( void );
  158.  
  159. /*--------------------------------------------------------------------*/
  160. /*    m a i n                                                         */
  161. /*                                                                    */
  162. /*    main program                                                    */
  163. /*--------------------------------------------------------------------*/
  164.  
  165. void main(int  argc, char  **argv)
  166. {
  167.    int c;
  168.    extern char *optarg;
  169.    extern int   optind;
  170.    COMMAND_CLASS command = LIST_DEFAULT;
  171.  
  172.    char *system = NULL;
  173.    char *userid = NULL;
  174.    char *job    = NULL;
  175.  
  176. /*--------------------------------------------------------------------*/
  177. /*     Report our version number and date/time compiled               */
  178. /*--------------------------------------------------------------------*/
  179.  
  180.    debuglevel = 0;
  181.    banner( argv );
  182.    fputc('\n', stdout );
  183.  
  184. #if defined(__CORE__)
  185.    copywrong = strdup(copyright);
  186.    checkref(copywrong);
  187. #endif
  188.  
  189.    if (!configure( B_UUIO ))
  190.       exit(1);   /* system configuration failed */
  191.  
  192. /*--------------------------------------------------------------------*/
  193. /*                   Switch to the spool directory                    */
  194. /*--------------------------------------------------------------------*/
  195.  
  196.    tzset();                      /* Set up time zone information  */
  197.    PushDir( spooldir );
  198.    atexit( PopDir );
  199.  
  200. /*--------------------------------------------------------------------*/
  201. /*        Process our arguments                                       */
  202. /*--------------------------------------------------------------------*/
  203.  
  204.    while ((c = getopt(argc, argv, "amqk:r:s:u:x:P:")) !=  EOF)
  205.       switch(c) {
  206.       case 'a':
  207.          command = LIST_ALL;
  208.          break;
  209.  
  210.       case 'm':
  211.          command = LIST_ACCESS;
  212.          system = optarg;
  213.          break;
  214.  
  215.       case 'q':
  216.          command = LIST_QUEUE;
  217.          break;
  218.  
  219.       case 'k':
  220.          command = KILL_JOB;
  221.          job = optarg;
  222.          break;
  223.  
  224.       case 'r':
  225.          command = REFRESH_JOB;
  226.          job = optarg;
  227.          break;
  228.  
  229.       case 's':
  230.          system = optarg;
  231.          break;
  232.  
  233.       case 'u':
  234.          userid = optarg;
  235.          break;
  236.  
  237.       case 'x':
  238.          debuglevel = atoi( optarg );
  239.          break;
  240.  
  241.       case 'P':
  242.          command = FORCE_POLL;
  243.          system = optarg;
  244.          break;
  245.  
  246.       case '?':
  247.          usage();
  248.    }
  249.    if (optind != argc) {
  250.       puts("Extra parameter(s) at end.");
  251.       exit(2);
  252.    }
  253.  
  254. /*--------------------------------------------------------------------*/
  255. /*                 Determine if we have a valid host                  */
  256. /*--------------------------------------------------------------------*/
  257.  
  258.    if( (system != NULL) && !equal( system , ALL ) )
  259.    {
  260.       struct HostTable *hostp = checkreal( system );
  261.  
  262.       if (hostp  ==  BADHOST)
  263.       {
  264.          printf("Unknown host \"%s\", program terminating.\n",
  265.                system );
  266.          panic();
  267.       }
  268.    } /* if */
  269.  
  270. /*--------------------------------------------------------------------*/
  271. /*                   Execute the requested command                    */
  272. /*--------------------------------------------------------------------*/
  273.  
  274.    switch ( command )
  275.    {
  276.       case LIST_DEFAULT:
  277.          if ( (system == NULL ) && ( userid == NULL) )
  278.          {
  279.             all( ALL, mailbox );
  280.             break;
  281.          }
  282.             /* Otherwise, fall through ... */
  283.  
  284.       case LIST_ALL:
  285.          if ( system == NULL )
  286.             system = ALL;
  287.          if ( userid == NULL )
  288.             userid = ALL;
  289.          all( system, userid );
  290.          break;
  291.  
  292.       case LIST_ACCESS:
  293.          if ( system == NULL )
  294.             system = ALL;
  295.          short_stats( system );
  296.          break;
  297.  
  298.       case LIST_QUEUE:
  299.          if ( system == NULL )
  300.             system = ALL;
  301.          long_stats( system );
  302.          break;
  303.  
  304.       case KILL_JOB:
  305.          kill_job( job );
  306.          break;
  307.  
  308.       case REFRESH_JOB:
  309.          refresh_job( job );
  310.          break;
  311.  
  312.       case FORCE_POLL:
  313.          poll( system );
  314.          break;
  315.  
  316.       default:
  317.          panic();
  318.  
  319.    } /* switch */
  320.    exit(0);
  321.  
  322. } /* main */
  323.  
  324. /*--------------------------------------------------------------------*/
  325. /*    a l l                                                           */
  326. /*                                                                    */
  327. /*    Report on all systems                                           */
  328. /*--------------------------------------------------------------------*/
  329.  
  330. void all( const char *system, const char *userid)
  331. {
  332.    char  canon[FILENAME_MAX];
  333.    long  size, ltime;
  334.    struct HostTable *hostp;
  335.    boolean hit = FALSE;
  336.  
  337.    if ( equal(system,ALL) )
  338.       hostp = nexthost( TRUE , aliasof );
  339.    else
  340.       hostp = checkreal( system );
  341.  
  342. /*--------------------------------------------------------------------*/
  343. /*                  Scan one or all host directories                  */
  344. /*--------------------------------------------------------------------*/
  345.  
  346.    while  (hostp !=  BADHOST )
  347.    {
  348.       char fname[FILENAME_MAX];
  349.  
  350. /*--------------------------------------------------------------------*/
  351. /*   Examine all of the files in the spool directory for this host    */
  352. /*--------------------------------------------------------------------*/
  353.  
  354.       while( readnext(fname , hostp->hostname, "C", NULL) )
  355.       {
  356.          boolean display = equal( userid, ALL );
  357.          struct data_queue *data_link = NULL;
  358.          char user[MAXL];
  359.          char sys[MAXL];
  360.  
  361.          strcpy(user,userid);       /* Nice default for the user     */
  362.                                     /* Generates more output if
  363.                                        straight copies in the queue  */
  364.          strcpy(sys, nodename);     /* Nice default for node as well */
  365.  
  366.          printmsg(1,"ALL(%s)", fname);
  367.          exportpath(canon, fname, hostp->hostname);
  368.  
  369. /*--------------------------------------------------------------------*/
  370. /*               Determine what kind of Call file it is               */
  371. /*--------------------------------------------------------------------*/
  372.  
  373.          switch(open_call(fname, hostp->hostname,
  374.                            &data_link, user, sys, JOB_STATUS))
  375.          {
  376.             case POLL_CALL:
  377.                if ( display )
  378.                {
  379.                   ltime = stater(fname, &size);
  380.                   hit = TRUE;
  381.                   printf( "%s %s %s\n",canon+2,dater(ltime, NULL),
  382.                         "(POLL)");
  383.                }
  384.                break;
  385.  
  386.             case SEND_CALL:
  387.             case RECEIVE_CALL:
  388.                if( equal(userid , ALL) || equal(userid, user))
  389.                   display = TRUE;
  390.  
  391.                if(display)
  392.                {
  393.                    hit = TRUE;
  394.                    print_all( canon + 2, data_link, user,
  395.                               hostp->hostname );
  396.                }
  397.                break;
  398.          } /* switch */
  399.  
  400.       } /* while */
  401.  
  402. /*--------------------------------------------------------------------*/
  403. /*    If processing all hosts, step to the next host in the queue     */
  404. /*--------------------------------------------------------------------*/
  405.  
  406.       if( equal( system , ALL ))
  407.          hostp = nexthost( FALSE , aliasof );
  408.       else
  409.          hostp = BADHOST;
  410.  
  411.    } /* while */
  412.  
  413.    if ( !hit )
  414.       printf("uustat: No jobs queued for system %s by user %s\n",
  415.                system , userid );
  416.  
  417. } /* all */
  418.  
  419. /*--------------------------------------------------------------------*/
  420. /*    p o l l                                                         */
  421. /*                                                                    */
  422. /*    Write a dummy call file to request a poll of a host             */
  423. /*--------------------------------------------------------------------*/
  424.  
  425. static void poll(const char *callee)
  426. {
  427.  
  428.    char tmfile[15];           /* Call file, UNIX format name         */
  429.    char msname[FILENAME_MAX];
  430.    FILE *stream;
  431.    static char *spool_fmt = SPOOLFMT;              /* spool file name */
  432.  
  433.    printmsg(1,"POLL(%s)", callee);
  434.    sprintf(tmfile, spool_fmt, 'C', callee,     'Z' , JobNumber( getseq() ));
  435.    importpath( msname, tmfile, callee);
  436.  
  437.    printmsg(1,"POLL(%s)", tmfile);
  438.  
  439.    stream = FOPEN( msname ,"w", BINARY);
  440.    if ( stream == NULL )
  441.    {
  442.       printerr( msname );
  443.       printmsg(0,"uustat: problem creating poll file %s (%s)",
  444.                tmfile, msname);
  445.       panic();
  446.    }
  447.    fclose( stream );
  448. } /* poll */
  449.  
  450.  
  451. /*--------------------------------------------------------------------*/
  452. /*    l o n g _ s t a t s                                             */
  453. /*                                                                    */
  454. /*    Report full information on jobs for a host                      */
  455. /*--------------------------------------------------------------------*/
  456.  
  457. /*--------------------------------------------------------------------*/
  458. /* fifi      1C     03/30-16:34 LOGIN FAILED Retry: 22:39 Count: 130  */
  459. /* helps     2C     03/30-16:32 SUCCESSFUL                            */
  460. /* im4u      5C(1)  03/30-06:50 LOGIN FAILED Retry: 11:15 Count: 9    */
  461. /* irasun           03/30-16:23 TALKING                               */
  462. /* killer    5C(6)  03/29-11:13 WRONG TIME TO CALL                    */
  463. /* radian    18C    03/30-16:42 WRONG TIME TO CALL                    */
  464. /* shemp      1C    03/30-14:43 LOGIN FAILED Retry: 20:48 Count: 107  */
  465. /* unisec     2C(1) 03/30-16:50 WRONG TIME TO CALL                    */
  466. /* ut-emx     1X    03/30-16:50 SUCCESSFUL                            */
  467. /*--------------------------------------------------------------------*/
  468.  
  469. static void long_stats( const char *system )
  470. {
  471.    struct HostTable *hostp;
  472.    time_t now = time( NULL );
  473.    boolean hit = FALSE;
  474.    time_t ltime;
  475.    long size;
  476.    char buf[BUFSIZ];
  477.  
  478.    HostStatus();              /* Load the host status table info     */
  479.  
  480. /*--------------------------------------------------------------------*/
  481. /*                  Get the first system to process                   */
  482. /*--------------------------------------------------------------------*/
  483.  
  484.    if ( equal(system,ALL) )
  485.       hostp = nexthost( TRUE , aliasof );
  486.    else
  487.       hostp = checkreal( system );
  488.  
  489. /*--------------------------------------------------------------------*/
  490. /*              Begin loop to display status of systems               */
  491. /*--------------------------------------------------------------------*/
  492.  
  493.    while(hostp != BADHOST )
  494.    {
  495.       char fname[FILENAME_MAX];
  496.                               /* Get list of files in the directory  */
  497.       size_t jobs = 0;        /* Declare, reset counter              */
  498.       time_t oldest_file = now;  /* Make the "oldest" file new       */
  499.  
  500. /*--------------------------------------------------------------------*/
  501. /*           Inner loop to count files and determine oldest           */
  502. /*--------------------------------------------------------------------*/
  503.  
  504.       while( readnext(fname, hostp->hostname, "C", NULL) != NULL )
  505.       {
  506.          ltime = stater( fname , &size);
  507.          if ((ltime > -1) && (ltime < oldest_file ))
  508.             oldest_file = ltime;
  509.  
  510.          jobs++;
  511.  
  512.       } /* while */
  513.  
  514. /*--------------------------------------------------------------------*/
  515. /*  We have all the information for this system; summary and display  */
  516. /*--------------------------------------------------------------------*/
  517.  
  518.       if ( jobs > 0 )
  519.       {
  520.          if (oldest_file + DAY < now)     /* File older than 24 hours?  */
  521.             sprintf( buf , "(%d)", (now - oldest_file) / DAY );
  522.                                           /* Yes --> Format info        */
  523.          else
  524.             *buf = '\0';                  /* No --> No, empty display   */
  525.  
  526.          printf("%-8.8s  %3dC%-4s  %s  %s\n", hostp->hostname, jobs , buf,
  527.                dater( hostp->hstats->lconnect , NULL ),
  528.                hostp->hstatus < last_status ?
  529.                      host_status[ hostp->hstatus ] :
  530.                      "*** INVALID/UNDOCUMENTED STATUS ***");
  531.          hit = TRUE;
  532.  
  533.       } /* if ( jobs > 0 ) */
  534.  
  535.       if (equal(system, ALL))
  536.          hostp = nexthost( FALSE , aliasof );
  537.       else
  538.          hostp = BADHOST;
  539.    } /* while */
  540.  
  541.    if ( !hit )
  542.       printf("uustat: No jobs queued for system %s\n", system );
  543. } /* long_stats */
  544.  
  545. /*--------------------------------------------------------------------*/
  546. /*    s h o r t _ s t a t s                                           */
  547. /*                                                                    */
  548. /*    Report access to a system                                       */
  549. /*--------------------------------------------------------------------*/
  550.  
  551. static void short_stats( const char *system )
  552. {
  553.    struct HostTable *hostp;
  554.  
  555.    HostStatus();              /* Load the host status table info     */
  556.  
  557. /*--------------------------------------------------------------------*/
  558. /*                  Get the first system to process                   */
  559. /*--------------------------------------------------------------------*/
  560.  
  561.    if ( equal(system,ALL) )
  562.       hostp = nexthost( TRUE , aliasof );
  563.    else
  564.       hostp = checkreal( system );
  565.  
  566. /*--------------------------------------------------------------------*/
  567. /*              Begin loop to display status of systems               */
  568. /*--------------------------------------------------------------------*/
  569.  
  570.    while(hostp != BADHOST )
  571.    {
  572.       printf("%-8.8s  %s  %s\n", hostp->hostname,
  573.             dater( hostp->hstats->lconnect , NULL ),
  574.             hostp->hstatus < last_status ?
  575.                   host_status[ hostp->hstatus ] :
  576.                   "*** INVALID/UNDOCUMENTED STATUS ***");
  577.  
  578.       if (equal(system, ALL))
  579.          hostp = nexthost( FALSE , aliasof );
  580.       else
  581.          hostp = BADHOST;
  582.    } /* while */
  583.  
  584. } /* short_stats */
  585.  
  586.  
  587. /*--------------------------------------------------------------------*/
  588. /*    k i l l _ j o b                                                 */
  589. /*                                                                    */
  590. /*    Kill a queued UUPC/extended job                                 */
  591. /*--------------------------------------------------------------------*/
  592.  
  593. static void kill_job(const char *jobid)
  594. {
  595.    char *system;              /* System name returned by is_job()    */
  596.    char host[FILENAME_MAX];
  597.    char canon[FILENAME_MAX];
  598.    char user[FILENAME_MAX];
  599.    char sys[FILENAME_MAX];
  600.  
  601.    strcpy(canon,"C.");
  602.    strcat(canon,jobid);
  603.    strcpy( user, "uucp");
  604.    system = is_job( canon ); /* Never returns if an error occurs     */
  605.    importpath( host, canon, system );
  606.                               /* Get the local name of the file      */
  607.    open_call(host, system, NULL, user, sys, JOB_KILL);
  608.    unlink( host );
  609.    printf("Deleted file %s (%s)\n", canon, host);
  610.    printf("Killed job %s (%s) queued for host %s by %s\n",
  611.             jobid, host, system, user);
  612.  
  613. } /* kill_job */
  614.  
  615. /*--------------------------------------------------------------------*/
  616. /*    r e f r e s h _ j o b                                           */
  617. /*                                                                    */
  618. /*    Refresh a job in the spool                                      */
  619. /*--------------------------------------------------------------------*/
  620.  
  621. static void refresh_job(const char *jobid)
  622. {
  623.    char *system;              /* System name returned by is_job()    */
  624.    char host[FILENAME_MAX];
  625.    char canon[FILENAME_MAX];
  626.    char user[FILENAME_MAX];
  627.    char sys[FILENAME_MAX];
  628.  
  629.    strcpy(canon,"C.");
  630.    strcat(canon,jobid);
  631.    strcpy( user, "uucp");
  632.    system = is_job( canon ); /* Never returns if an error occurs     */
  633.    importpath( host, canon, system );
  634.                               /* Get the local name of the file      */
  635.    open_call(host, system, NULL, user, sys, JOB_REFRESH);
  636.    touch( host );
  637.    printf("Rejuvenated job %s (%s) queued for host %s by %s\n",
  638.             jobid, host, system, user);
  639.  
  640. } /* refresh_job */
  641.  
  642. /*--------------------------------------------------------------------*/
  643. /*    o p e n _ c a l l                                               */
  644. /*                                                                    */
  645. /*    Process a call file                                             */
  646. /*--------------------------------------------------------------------*/
  647.  
  648. static CALLTYPE open_call( const char *callname,
  649.                            const char *remote,
  650.                                  struct data_queue **top,
  651.                                  char *user,
  652.                                  char *sys,
  653.                            const CALL_ACTION action )
  654. {
  655.    FILE *stream;
  656.    char buf[BUFSIZ];
  657.    struct data_queue *current;
  658.    CALLTYPE this_call = POLL_CALL;
  659.  
  660.    char host[FILENAME_MAX];
  661.    char type[FILENAME_MAX], fname[FILENAME_MAX], tname[FILENAME_MAX];
  662.    char flgs[FILENAME_MAX], dname[FILENAME_MAX];
  663.  
  664.    current = NULL;
  665.  
  666. /*--------------------------------------------------------------------*/
  667. /*                    Open the file for processing                    */
  668. /*--------------------------------------------------------------------*/
  669.  
  670.    printmsg(2,"Scanning call file \"%s\"", callname );
  671.    stream = FOPEN( callname, "r", TEXT );
  672.  
  673.    if ( stream == NULL )
  674.    {
  675.       printerr( callname );
  676.       panic();
  677.    }
  678.  
  679.    while( fgets( buf, BUFSIZ, stream) != NULL)
  680.    {
  681.       switch (*buf)
  682.       {
  683.          case '#':
  684.             break;
  685.  
  686.          case 'S':
  687.          case 'R':
  688.             *dname = '\0';
  689.             sscanf(buf, "%s %s %s %s %s %s",
  690.                          type, fname, tname, user , flgs, dname);
  691.             this_call = *type;
  692.  
  693.             if ( ! strlen( dname ) )
  694.             {
  695.                printmsg(0,"Invalid data in call file \"%s\"",callname);
  696.                panic();
  697.             }
  698.  
  699. /*--------------------------------------------------------------------*/
  700. /*    If returning job status, allocate next link in status queue     */
  701. /*--------------------------------------------------------------------*/
  702.  
  703.             if ( action == JOB_STATUS )
  704.             {
  705.               if ( current == NULL)
  706.                  *top = current = malloc( sizeof *current );
  707.               else {
  708.                  current->next_link = malloc( sizeof *current );
  709.                  current = current->next_link;
  710.               }
  711.               checkref( current );
  712.  
  713.               current->next_link = NULL;
  714.               current->type      = *buf;
  715.             } /* action */
  716.  
  717. /*--------------------------------------------------------------------*/
  718. /*    Get the UNIX and local filenames for data file to be            */
  719. /*    processed; we always report the original file name, but we      */
  720. /*    always look at and/or update the spool copy of the data; we     */
  721. /*    never alter or delete the original                              */
  722. /*--------------------------------------------------------------------*/
  723.  
  724.             if ( this_call == SEND_CALL )
  725.             {
  726.                if (equal(dname, "D.0"))
  727.                   importpath( host, fname, remote );
  728.                else
  729.                   importpath( host, dname, remote );
  730.  
  731.                switch  ( action )
  732.                {
  733.                   case JOB_STATUS:
  734.                      current->created   = stater( host,  ¤t->size);
  735.                      if ((current->created != -1) &&
  736.                          (equaln(tname ,"X.",2)))  /* Execute file?  */
  737.                      {
  738.                         open_data( host, user, sys, current->name );
  739.                         current->execute = TRUE;
  740.                      }
  741.                      else {
  742.                         current->execute = FALSE;
  743.                         strcpy( current->name , fname );
  744.                      }
  745.                      break;
  746.  
  747.                   case JOB_KILL:
  748.                      if ((current->created != -1) && !equal(dname, "D.0"))
  749.                      {
  750.                         unlink( host );
  751.                         printf("Deleted file %s (%s)\n", dname, host);
  752.                      }
  753.                      break;
  754.  
  755.                   case JOB_REFRESH:
  756.                      if ((current->created != -1) && !equal(dname, "D.0"))
  757.                         touch( host );
  758.                      break;
  759.  
  760.                   default:
  761.                      panic();
  762.                } /* switch */
  763.             }
  764.             else if ( action == JOB_STATUS )
  765.             {
  766.                current->execute = FALSE;
  767.                strcpy( current->name , fname );
  768.                current->created = stater( callname, ¤t->size);
  769.             }
  770.  
  771.             break;
  772.  
  773.          default:
  774.             printmsg(0,"Invalid line \"%s\" in call file \"%s\"",
  775.                               buf, callname);
  776.             break;
  777.       } /* switch */
  778.    } /* while */
  779.  
  780. /*--------------------------------------------------------------------*/
  781. /*                   Clean up and return to caller                    */
  782. /*--------------------------------------------------------------------*/
  783.  
  784.    if (ferror( stream ))
  785.    {
  786.       printerr( callname );
  787.       clearerr( stream );
  788.    }
  789.  
  790.    fclose( stream );
  791.    return this_call;
  792.  
  793. } /* open call */
  794.  
  795.  
  796. /*--------------------------------------------------------------------*/
  797. /*    o p e n _ d a t a                                               */
  798. /*                                                                    */
  799. /*    Process a single execute file                                   */
  800. /*--------------------------------------------------------------------*/
  801.  
  802. static void open_data(const char *file,
  803.                       char *user,
  804.                       char *sys,
  805.                       char *command)
  806. {
  807.    FILE  *data_fp;
  808.    char  data_buf[BUFSIZ];
  809.    char  *token ;
  810.    static char f_name[ FILENAME_MAX ];
  811.    size_t  bytes = 0;
  812.  
  813.    printmsg(1,"INSIDE OPEN_DATA(%s)",file);
  814.    *f_name = '\0';
  815.  
  816.    printmsg(1,"OPENING(%s)",file);
  817.    data_fp = FOPEN(file, "r", BINARY);
  818.    if(data_fp ==  NULL){
  819.       printerr( file );
  820.       panic();
  821.    }
  822.    printmsg(1,"OPEN (%s) SIZE (%d)", file, BUFSIZ);
  823.  
  824.    while(fgets(data_buf, (int) BUFSIZ, data_fp) !=  NULL){
  825.  
  826.       size_t len = strlen( data_buf );
  827.       bytes += strlen( data_buf );
  828.       if ( data_buf[ --len ] == '\n')
  829.          data_buf[ len ] = '\0';
  830.  
  831. /*--------------------------------------------------------------------*/
  832. /*                 Determine what kind of line it is                  */
  833. /*--------------------------------------------------------------------*/
  834.  
  835.       switch(data_buf[0]){
  836.          case '#':
  837.          printmsg(5,"COMMENT %s", data_buf);
  838.             break;
  839.  
  840.           case 'U':
  841.             token = strtok( data_buf + 1, WHITESPACE );
  842.             if ( token == NULL )
  843.                break;
  844.             strncpy( user, token , MAXL );
  845.             user[ MAXL-1 ] = '\0';
  846.             token = strtok( NULL , WHITESPACE );
  847.             if ( token == NULL )
  848.                break;
  849.             strncpy(  sys, token , MAXL);
  850.             sys[ MAXL-1 ] = '\0';
  851.             printmsg(1,"SYSTEM = (%s), USER = (%s)",sys,user);
  852.             break;
  853.  
  854.          case 'F':
  855.             printmsg(5,"File %s", data_buf);
  856.             token = strtok( data_buf + 1 , WHITESPACE );
  857.             strncpy( f_name, token , FILENAME_MAX );
  858.             f_name[ FILENAME_MAX - 1 ] = '\0';
  859.             break;
  860.  
  861.          case 'I':
  862.             printmsg(5,"Input %s", data_buf);
  863.             break;
  864.  
  865.          case 'C':
  866.             printmsg(1,"Command %s", data_buf);
  867.             token = strchr(data_buf,' ') + 1;
  868.             strncpy(command, token , FILENAME_MAX - 1);
  869.             command[ FILENAME_MAX - 1] = '\0';
  870.             break;
  871.          default:
  872.             printmsg(1,"UNKNOWN LINE %s", data_buf);
  873.             break;
  874.       } /* switch */
  875.    } /* while */
  876.  
  877.    printmsg(1,"CLOSED (%s), bytes = %d, d file = %s", file, bytes, token);
  878.    fclose(data_fp);
  879. } /* open_data */
  880.  
  881. /*--------------------------------------------------------------------*/
  882. /*    p r i n t _ a l l                                               */
  883. /*                                                                    */
  884. /*    Print all the information related to a job in the spool         */
  885. /*--------------------------------------------------------------------*/
  886.  
  887. static void print_all(       char *job,
  888.                              struct data_queue *current ,
  889.                        const char *user,
  890.                        const char *sys )
  891. {
  892.    char blanks[FILENAME_MAX];
  893.    size_t subscript = 0;
  894.  
  895. /*--------------------------------------------------------------------*/
  896. /*  Create a blank buffer for printing all of the first line of data  */
  897. /*--------------------------------------------------------------------*/
  898.  
  899.    while ( job[subscript] != '\0')
  900.       blanks[subscript++] = ' ';
  901.    blanks[ subscript ] = '\0';
  902.  
  903. /*--------------------------------------------------------------------*/
  904. /*                Loop through the files for this job                 */
  905. /*--------------------------------------------------------------------*/
  906.  
  907.    while ( current != NULL )
  908.    {
  909.       struct data_queue *save_data = current->next_link;
  910.       if ( current->execute)
  911.          printf("%s %s %c %-8.8s %-8.8s %s\n", job,
  912.                      dater( current->created, NULL ),
  913.                      current->type,
  914.                      sys, user, current->name );
  915.       else
  916.          printf("%s %s %c %-8.8s %-8.8s %ld %s\n", job,
  917.                      dater( current->created, NULL ),
  918.                      current->type,
  919.                      sys, user, current->size , current->name );
  920.  
  921.       job = blanks;           /* Don't print job name more than once */
  922.       free( current );        /* Release the abused storage          */
  923.       current = save_data;
  924.    } /* while */
  925.  
  926. } /* print_all */
  927.  
  928. /*--------------------------------------------------------------------*/
  929. /*    i s _ j o b                                                     */
  930. /*                                                                    */
  931. /*    Determine if a file is a valid job                              */
  932. /*                                                                    */
  933. /*    The task of finding a proper job made is harder by the fact     */
  934. /*    UUPC inserts all these jobs into separate directories.  We      */
  935. /*    brute force it, checking all known hosts for the wayward        */
  936. /*    file.  This is relatively cheap, since most hosts will fail     */
  937. /*    on the host name and thus we never look on disk.  Since job     */
  938. /*    sequence numbers are global across UUPC/extende, a false hit    */
  939. /*    on the host doesn't hurt because the job number will never      */
  940. /*    match.                                                          */
  941. /*--------------------------------------------------------------------*/
  942.  
  943. static char *is_job(const char *callfile)
  944. {
  945.    struct HostTable *hostp;
  946.    char host[FILENAME_MAX];
  947.    boolean hit = FALSE;
  948.  
  949. /*--------------------------------------------------------------------*/
  950. /*                  Get the first system to process                   */
  951. /*--------------------------------------------------------------------*/
  952.  
  953.       hostp = nexthost( TRUE , aliasof );
  954.  
  955. /*--------------------------------------------------------------------*/
  956. /*              Begin loop to display local system                    */
  957. /*--------------------------------------------------------------------*/
  958.  
  959.    while(hostp != BADHOST )
  960.    {
  961.       if (equaln(hostp->hostname, &callfile[2],
  962.                 min( strlen( hostp->hostname ), HOSTLEN)))
  963.                               /* Right host?                         */
  964.       {                       /* Maybe --> Look for the file         */
  965.          importpath( host, callfile, hostp->hostname);
  966.          if ( !access( host, 0 ))   /* Does the host file exist?     */
  967.             return hostp->hostname; /* Yes --> Return success        */
  968.          hit = TRUE;
  969.       }
  970.  
  971.       hostp = nexthost( FALSE , aliasof );
  972.    } /* while */
  973.  
  974. /*--------------------------------------------------------------------*/
  975. /*          We didn't get the host; report an error and exit          */
  976. /*--------------------------------------------------------------------*/
  977.  
  978.    if ( hit )
  979.       printf("Unable to locate call file %s -- run uustat -a\n", callfile );
  980.    else
  981.       printf("Unable to locate call file %s -- hostname may be incorrect\n",
  982.                callfile);
  983.    exit(1);
  984.    return NULL;                  /* Make C compiler happy */
  985. } /* is_job */
  986.  
  987. /*--------------------------------------------------------------------*/
  988. /*    t o u c h                                                       */
  989. /*                                                                    */
  990. /*    Update list modified time for a file by opening and closing it  */
  991. /*--------------------------------------------------------------------*/
  992.  
  993. static void touch( const char *fname)
  994. {
  995.    printf("touch: function not available.  Parameter was \"%s\"\n",
  996.             fname);
  997. } /* touch */
  998.  
  999.  
  1000. /*--------------------------------------------------------------------*/
  1001. /*    u s a g e                                                       */
  1002. /*                                                                    */
  1003. /*    Report how to use program                                       */
  1004. /*--------------------------------------------------------------------*/
  1005.  
  1006. static void usage( void )
  1007. {
  1008.    fputs("Usage:\tuustat\t[-m | -q | -a] [-u userid | all ] [-s system | all]\n\
  1009. \t\t[-k | -r ] jobid\n\
  1010. \t\t[-P system]\n\n\
  1011. \tDefault is to display jobs queued by current user.\n\
  1012. \t-a\t\tDisplays all jobs for all users.\n\
  1013. \t-k jobid\t\tKills job \"jobid\"\n\
  1014. \t-m\t\tDisplays accessability of known systems.\n\
  1015. \t-q\t\tDisplays summary of queues for systems with work.\n\
  1016. \t-r jobid\t\tRefreshes timestamps on job \"jobid\"\n\
  1017. \t-s system\tRestricts output to system.\n\
  1018. \t-u userid\tRestricts output to userid. (Ignored by -k -m -P -q -r)\n\
  1019. \t-P system\tQueues dummy job for system \"system\" to force poll\n",
  1020.             stdout );
  1021.    exit(1);
  1022. } /* usage */
  1023.